//引入登录|退出登录|获取用户信息的接口函数
import { login, logout, getInfo } from '@/api/user'
//token相关
import { getToken, setToken, removeToken } from '@/utils/auth'
//路由模块中的重置路由
import { anyRoutes, asyncRoutes, constantRoutes, resetRouter } from '@/router'

import router from '@/router'

const getDefaultState = () => {
  return {
    //获取token
    token: getToken(),
    //存储用户名
    name: '',
    //存储用户头像
    avatar: '',
    //服务器返回的菜单信息【根据不同的角色，返回的信息不同】
    routes: [],
    //按钮权限信息
    buttons: [],
    //用户角色
    roles: [],
    //对比后【项目中已有的异步路由，与服务器返回的标记信息进行对比最终需要展示的路由】
    resultAsyncRoutes: [],
    //用户最终展示的全部路由
    resultAllRoutes: []
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_USERINFO: (state, userInfo) => {
    state.name = userInfo.name
    state.avatar = userInfo.avatar
    state.routes = userInfo.routes
    state.buttons = userInfo.buttons
    state.roles = userInfo.roles
  },
  //最终计算出来的异步路由
  SET_RESULTASYNCROUTES: (state, asyncRoutes) => {
    //vuex保存当前用户的异步路由，注意：一个用户需要展示：常量路由、异步路由、任意路由
    state.resultAsyncRoutes = asyncRoutes
    //计算出当前用户需要展示的所有路由
    state.resultAllRoutes = constantRoutes.concat(state.resultAsyncRoutes, anyRoutes)
    //给路由器添加新的路由
    router.addRoutes(state.resultAllRoutes)
  }
}

const actions = {
  // 用户登录
  async login({ commit }, userInfo) {
    const { username, password } = userInfo
    let result = await login({ username: username.trim(), password: password })
    if (result.code == 20000) {
      commit('SET_TOKEN', result.data.token)
      setToken(result.data.token)
      return 'OK'
    } else {
      return Promise.reject(new Error(result.messsage || '登录失败'))
    }
  },

  // 获取用户信息
  async getInfo({ commit, state }) {
    let result = await getInfo(state.token)
    console.log(result)
    if (result.code == 20000) {
      if (!result.data) {
        return Promise.reject(new Error(result.message))
      }
      // result.data 返回数据包括：
      //用户名name
      //用户头像avatar
      //routes：[返回的标志：不同的用户应该展示哪些路由]
      //roles：用户角色信息
      //buttons：[按钮信息：按钮权限的标记]
      const { data } = result
      commit('SET_USERINFO', data)
      commit('SET_RESULTASYNCROUTES', computedAsyncRoutes(asyncRoutes, data.routes))
      return '获取用户信息成功'
    } else {
      return Promise.reject(new Error(result.message || '获取用户信息失败！'))
    }
  },

  // 用户登出
  async logout({ commit, state }) {
    let result = await logout(state.token)
    console.log(result)
    if (result.code == 20000) {
      removeToken() // 必须先清除token
      resetRouter()
      commit('RESET_STATE')
      return '登出成功'
    } else {
      return Promise.reject(new Error(result.message || '登出失败'))
    }
  },

  // 移除token
  resetToken({ commit }) {
    return new Promise((resolve) => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

//最终计算出来的异步路由
const computedAsyncRoutes = (asyncRoutes, routes) => {
  //过滤出当前用户需要展示的异步路由
  return asyncRoutes.filter((item) => {
    if (routes.indexOf(item.name) != -1) {
      //递归：别忘记还有子路由【二级路由、三级路由等等】
      if (item.children && item.children.length) {
        item.children = computedAsyncRoutes(item.children, routes)
      }
      return true
    }
  })
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
